package dataStructures;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.management.RuntimeErrorException;

public class CodeBook{
	
	private int clusterId;
	private int[] ids;
	private double[] codeValues;

	public CodeBook() {
	}
		
	public CodeBook(int clusterId, int[] ids, double[] codeValues) {
		super();
		this.clusterId = clusterId;
		this.ids = ids;
		this.codeValues = codeValues;
	}
	
	public static CodeBook getCBfromString(String line) {
		CodeBook cb = null;
		
		int clId = -1;
		int[] ids;
		double[] cValues = null;
		
		String[] Strings = line.split("\t");
		clId = Integer.parseInt(Strings[0]);
		
		String[] idStrings = Strings[1].substring(1, Strings[1].length() - 1).split(",");
		ids = new int[idStrings.length];
		for (int i = 0; i < idStrings.length; i++) {
			ids[i] = Integer.parseInt(idStrings[i].trim());
		}
		
		String[] cValuesStrings = Strings[2].substring(1, Strings[2].length() - 1).split(",");
		
		if (!cValuesStrings[0].isEmpty()){
			cValues = new double[cValuesStrings.length];
			for (int i = 0; i < cValuesStrings.length; i++) {
				cValues[i] = Double.parseDouble(cValuesStrings[i].trim());
			}
		}
		cb = new CodeBook(clId, ids, cValues);
		
		return cb;
	}
	
	public int[] getUserIds(){
		return this.ids;
	}
	
	public double[] getCodeValues(){
		return this.codeValues;
	}
	
	public int getClusterId(){
		return clusterId;
	}
	
	
	public static Vector<CodeBook> fromFile(File  codebook){
		Vector<CodeBook> cb = new Vector<CodeBook>();
		String line , cluster ,ids ,cv ;
		StringTokenizer tabTokenizer;

			  FileInputStream fstream = null;
			
				try {
					fstream = new FileInputStream(codebook);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
					throw new RuntimeException(e);
					
				}
			
			  // Get the object of DataInputStream
			  DataInputStream in = new DataInputStream(fstream);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  //Read File Line By Line
			  try {
				while ((line = br.readLine()) != null)   {
					  tabTokenizer = new StringTokenizer(line, "\t");
					   cluster = tabTokenizer.nextToken();
					   ids = tabTokenizer.nextToken();
					   cv = tabTokenizer.nextToken();
					   cb.add(new CodeBook(Integer.parseInt(cluster) ,readIDs(ids) , readCodeBookValues(cv) ));
				  }
				in.close();
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException();
			}
			  
			  
			  return cb;
			
	
		
			  
		
		
		
	}

	private static int[] readIDs(String ids2) {
		ArrayList<Integer> a = new ArrayList<Integer>(); //the array of ids that belongs to the cluster
		StringTokenizer st = new StringTokenizer(ids2 , "[]\t\n, ");
		
		while(st.hasMoreTokens()){
			a.add(Integer.parseInt(st.nextToken()));
		}
		
		int [] ans = new int[a.size()];
		for(int i = 0 ; i < ans.length ; i++){
			ans[i] = a.get(i);
		}
		
		return ans;
	}

	private static double[] readCodeBookValues(String cv) {
		ArrayList<Double> a = new ArrayList<Double>(); //the array of ids that belongs to the cluster
		StringTokenizer st = new StringTokenizer(cv , "[]\t\n, ");
		
		while(st.hasMoreTokens()){
			a.add(Double.parseDouble(st.nextToken()));
		}
		
		double [] ans = new double[a.size()];
		for(int i = 0 ; i < ans.length ; i++){
			ans[i] = a.get(i);
		}
		
		return ans;
	}
	
}
